using System;
using Arcane.Source.Data;
using Arcane.Source.Combat;
using Godot;

namespace Arcane.Source.Client
{
    public static class EntityScriptingApi
    {
        public static Variant Attack(this Entity e, Variant[] parameters)
        {
            if (!parameters.TryTake(3, out var iter)) goto Fail;

            if (!Iter.TryPop<int>(ref iter, out var targetIdx)) goto Fail;
            if (!Iter.TryPop<short>(ref iter, out var damageType)) goto Fail;
            if (!Iter.TryPop<float>(ref iter, out var damage)) goto Fail;

            var target = e.GetTarget(targetIdx);
            var dmgType = (DamageType)damageType;
            e.Attack(target, dmgType, damage);

            return new();

            Fail:
            GD.PrintErr($"Script failed on (attack {string.Join(' ', parameters)})");
            return new();
        }

        public static Variant Hurt(this Entity e, Variant[] parameters)
        {
            if (!parameters.TryTake(2, out var iter)) goto Fail;

            if (!Iter.TryPop<short>(ref iter, out var damageType)) goto Fail;
            if (!Iter.TryPop<float>(ref iter, out var damage)) goto Fail;

            e.Hurt((DamageType)damageType, damage);

            return new();

            Fail:
            GD.PrintErr($"Script failed on (hurt {string.Join(' ', parameters)})");
            return new();
        }


        public static Variant Attach(this Entity e, Variant[] parameters)
        {
            if (!parameters.TryTake(2, out var iter)) goto Fail;

            if (!Iter.TryPop<int>(ref iter, out var targetIdx)) goto Fail;
            if (!Iter.TryPop<StringName>(ref iter, out var triggerName)) goto Fail;
            if (!Iter.TryPop<Godot.Collections.Array>(ref iter, out var effectCons)) goto Fail;

            var effectName = effectCons[0].AsStringName();
            effectCons.RemoveAt(0);

            e.GetTarget(targetIdx).AddTrigger(triggerName, GameDB.StatusEffect.Create(effectName, effectCons));

            throw new NotImplementedException();

            Fail:
            GD.PrintErr($"Script failed on (attach {string.Join(' ', parameters)})");
            return new();
        }
        
        public static Variant GetProperty(this Entity e, string name) => name switch
        {
            "health" => e.Health,
            "energy" => e.Energy,
            "max-health" => e.maxHealth,
            "max-energy" => e.MaxEnergy,
            _ => new(),
        };
    }
}